package me.zhengjie.common;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.UUIDGenerator;

import javax.persistence.Id;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Slf4j
public class ExamUuidGenerator  extends UUIDGenerator {
    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException {
        Class<?> clazz = obj.getClass();
        log.debug("generate id class: {}", clazz.getName());
        Field[] fields = clazz.getDeclaredFields();
        try {
            for (Field field : fields) {
                Id idAnnotation = field.getAnnotation(Id.class);
                if (idAnnotation == null) {
                    continue;
                }
                String fieldName = field.getName();
                log.debug("field name: {}", fieldName);
                String getMethodName = generateGetMethodName(fieldName);
                log.debug("get method name: {}", getMethodName);
                Method declaredMethod = clazz.getDeclaredMethod(getMethodName);
                String idValue = (String) declaredMethod.invoke(obj);
                if (StrUtil.isNotBlank(idValue)) {
                    log.debug("use set value: {}", idValue);
                    return idValue;
                }
            }
        } catch (NoSuchMethodException e) {
            log.error("no such method", e);
        } catch (InvocationTargetException | IllegalAccessException e) {
            log.error("invoke exception", e);
        }

        return super.generate(session, obj);
    }
    private String generateGetMethodName(String fieldName) {
        return "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    }
}
